﻿using System;
using System.Collections.Generic;
using System.Text;
using Galaxy.ModuleInterface;

namespace Galaxy.Loader
{
    /// <summary>Модулб-загрузчик</summary>
    public class CLoader : Galaxy.ModuleInterface.CGalaxyModule
    {
        /* - События ------------------------------------------------------------------------------------- */

        #region События

        /// <summary>
        /// Событие возникает, когда модуль загружает объект по указаной информации из настроечного файла
        /// </summary>
        public event OnObjectLoadedEventHandler OnObjectLoaded;

        /// <summary>Генерация события загрузки объекта</summary>
        /// <param name="Args">Аргумент события загрузки объекта</param>
        protected virtual void Invoke_OnObjectLoaded(OnObjectLoadedEventArgs Args)
        {
            if(OnObjectLoaded != null)
                OnObjectLoaded.Invoke(this, Args);
        }

        /// <summary>Генерация события загрузки объекта</summary>
        /// <param name="Object">Загруженый объект</param>
        protected virtual void Invoke_OnObjectLoaded(object Object)
        {
            if(Object == null) return;
            Invoke_OnObjectLoaded(new OnObjectLoadedEventArgs(Object));
            Invoke_OnModuleLoaded(Object as ModuleInterface.IGalaxyModule);
        }

        /// <summary>Событие возникает когда загрузчик загружает модуль Галактики</summary>
        public event OnModuleLoadedEventHandler OnModuleLoaded;

        /// <summary>Генерация события загрузки модуля</summary>
        /// <param name="Args">Аргументы события</param>
        protected virtual void Invoke_OnModuleLoaded(OnModuleLoadedEventArgs Args)
        {
            if(OnModuleLoaded != null)
                OnModuleLoaded.Invoke(this, Args);
        }

        /// <summary>Герерация события загрузки модуля</summary>
        /// <param name="Module">Загруженый модуль</param>
        protected virtual void Invoke_OnModuleLoaded(ModuleInterface.IGalaxyModule Module)
        {
            if(Module == null) return;
            Invoke_OnModuleLoaded(new OnModuleLoadedEventArgs(Module));
        }

        #endregion

        /* - Поля ---------------------------------------------------------------------------------------- */

        #region Поля

        /// <summary>Список загружаемых объектов</summary>
        private Information.CObjectList f_LoadedObjects;

        /// <summary>Проинициализирован</summary>
        private bool f_Initialized = false;

        /// <summary>Включён</summary>
        private bool f_Enabled = false;

        #endregion

        /* - Свойства ------------------------------------------------------------------------------------ */

        #region Свойства

        /// <summary>Имя файла со списком объектов</summary>
        protected string StorageFileName { get { return this.Name + ".Объекты.xml"; } }
        /// <summary>Загрузчик инициализирован</summary>
        public override bool Initialized { get { return f_Initialized; } }
        /// <summary>Загрузчик запущен</summary>
        public override bool Enable
        {
            get { return f_Enabled; }
            set { if(value) Start(); else Stop(); }
        }

        #endregion

        /* - Конструкторы -------------------------------------------------------------------------------- */

        #region Конструкторы

        /// <summary>Инициализация нового модуля загрузчика</summary>
        public CLoader() : base("Загрузчик") { }

        #endregion

        /* - Методы -------------------------------------------------------------------------------------- */

        #region Методы

        /// <summary>Запуск загрузчика</summary>
        public override void Start()
        {
            if(Enable) return;

            object[] lv_LoadedObjects = f_LoadedObjects.CreateAll();
            Array.ForEach<object>(lv_LoadedObjects, Invoke_OnObjectLoaded);

            f_Enabled = true;
        }

        /// <summary>Остановка загрузчика</summary>
        public override void Stop()
        {
            if(!Enable) return;
            ConnectedModules.ForEach(delegate(IGalaxyModule Module)
            {
                if(!f_LoadedObjects.Contains(Module))
                    if(Module != this)
                        f_LoadedObjects.Add(Module);
            });

            f_LoadedObjects.SerializeXML(this.StorageFileName);
            f_LoadedObjects = null;
            f_Initialized = false;
            f_Enabled = false;
        }

        /// <summary>Инициализация загрузчика</summary>
        public override void Initialize()
        {
            if(System.IO.File.Exists(this.StorageFileName))
                f_LoadedObjects = Information.CObjectList.DeserializeXML(this.StorageFileName);
            else
                f_LoadedObjects = new Galaxy.Loader.Information.CObjectList();
        }

        #endregion

        /* ----------------------------------------------------------------------------------------------- */
    }
}
